#include <iostream>
#include <websocketpp/config/asio_no_tls.hpp>
#include <websocketpp/server.hpp>

// 定义 Server 类型
typedef websocketpp::server<websocketpp::config::asio> server_t;

void onOpen(websocketpp::connection_hdl hdl){
    std::cout << "webSocket 长连接建立成功!\n";
}
void onClose(websocketpp::connection_hdl hdl){
    std::cout << "webSocket 长连接断开!\n";
}

void onMessage(server_t *server, websocketpp::connection_hdl hdl, server_t::message_ptr msg){
    // 1. 获取有效信息载荷数据, 来进行业务处理
    std::string body = msg->get_payload();
    std::cout << "收到消息: " << body << std::endl;

    // 2. 对客户端进行响应
      // 2.1 获取通信连接
    auto conn = server->get_con_from_hdl(hdl);
      // 2.2 发送数据
    conn->send(body + "-Hello!", websocketpp::frame::opcode::value::text);
}

int main(){
    // 1. 实例化服务器对象
    server_t server;
    // 2. 初始化日志输出 -- 关闭日志输出
    server.set_access_channels(websocketpp::log::alevel::none);
    // 3. 初始化 asio 框架
    server.init_asio();
    // 4. 设置 消息处理/连接获取成功/连接关闭回调函数
    server.set_open_handler(onOpen);
    server.set_close_handler(onClose);
    
    // typedef lib::function<void(connection_hdl,message_ptr)> message_handler;
    // 给我任何一个 可调用对象（函数指针、函数对象、lambda、std::function…）, 调用时会传给两个实参：connection_hdl hdl 和 message_ptr msg
    // void onMessage(server_t *s, connection_hdl h, message_ptr m);
    auto msg_handler = std::bind(onMessage, &server, std::placeholders::_1, std::placeholders::_2);
    server.set_message_handler(msg_handler); // 匹配签名

    // 5. 启用地址重用
    server.set_reuse_addr(true);
    // 6. 设置监听端口 & 开始监听
    server.listen(9002);
    server.start_accept();
    // 7. 启动服务器
    server.run();
    return 0;
}